package org.scala.javafx.diagnostics

import org.scala.javafx.rich.Enrich._
import javafx.stage.Stage
import javafx.stage.StageStyle
import javafx.scene.Scene
import javafx.scene.layout.Pane
import javafx.scene.Group
import javafx.scene.Node
import javafx.stage.PopupWindow
import javafx.scene.shape.Path
import javafx.scene.shape.MoveTo
import javafx.scene.shape.LineTo
import javafx.scene.shape.ClosePath
import javafx.stage.Popup
import javafx.stage.Window
import javafx.scene.shape.Rectangle
import scala.collection.JavaConverters._
import javafx.scene.layout.Region
import javafx.animation.KeyFrame
import javafx.util.Duration
import javafx.animation.KeyValue
import javafx.beans.value.WritableValue
import javafx.animation.Interpolator
import org.scala.javafx.geometry.Bounds2D
import org.scala.javafx.geometry.Point2D
import javafx.scene.input.MouseEvent
import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.ObjectProperty
import javafx.event.EventHandler
import javafx.event.ActionEvent

class SpyScope {
  var rectangle: SpyRectangle = null
  
  val subjectProperty: ObjectProperty[Object] = new SimpleObjectProperty[Object]
  def subject = subjectProperty.get()
  def subject_=(newSubject: Object): Unit = subjectProperty.set(newSubject)

  subjectProperty.addChangeListener { (_, oldValue, newValue) =>
    if (oldValue != newValue) {
      val source = oldValue match {
        case window: Window => Some(Bounds2D.of(window))
        case scene: Scene => Some(Bounds2D.fromScreenOf(scene))
        case node: Node => Some(Bounds2D.fromScreenOf(node))
        case _ => None
      }
      println("--> source: " + oldValue)
      val target = newValue match {
        case window: Window => Some(Bounds2D.of(window))
        case scene: Scene => Some(Bounds2D.fromScreenOf(scene))
        case node: Node => Some(Bounds2D.fromScreenOf(node))
        case _ => None
      }
      println("--> target: " + newValue)
      if (source != target) {
        val usingSource = source.getOrElse { target.get.inflate(25.0) }
        val usingTarget = target.getOrElse { source.get.inflate(25.0) }
        
        SpyScopeGlass.onAny(newValue).orElse(SpyScopeGlass.onAny(oldValue)).foreach { spyScopeGlass =>
          println(spyScopeGlass)
          if (source == None) {
            this.rectangle = new SpyRectangle()
            newValue match {
              case node: Node => {
                rectangle.forwardMouseEventsTo(node.getScene())
              }
              case _ => {
              }
            }
            spyScopeGlass.screenGroup.getChildren().addDistinct(this.rectangle)
            rectangle.appear(spyScopeGlass, usingTarget)
          } else if (target == None) {
            rectangle.disappear(spyScopeGlass, usingSource)
          } else {
            rectangle.move(spyScopeGlass, usingSource, usingTarget)
          }
        }
      }
    }
  }
  
}

object SpyScope {
  def on(node: Node) = {
     
  }
}
